<template>
    <div>
      <div class="tips">本项目ui基于iview ui。</div>
      <div v-show="codeShowFlag" style="margin-top:10px;text-align:right">
        <Button @click="flushCode()">刷新</Button>
        <Button type="primary" data-clipboard-action="copy"
        :data-clipboard-text="previewCode + '\n<script>\n  ' +previewJSCode+ '\n</script>\n<style scoped>\n</style>'" class="codeBtn" @click="copy">复制</Button>
      </div>
      <pre v-highlight v-if="codeShowFlag">
        <code style="white-space: break-spaces;word-break: break-all;">
          {{previewCode}}
          {{"&lt;script&gt;"}}
          {{previewJSCode}}
          {{"&lt;/script&gt;"}}
          {{"&lt;style scoped&gt;"}}
          {{"&lt;/style&gt;"}}
          <!-- <Input :value="previewCode + '\n<script>\n  ' +previewJSCode+ '\n</script>\n<style scoped>\n</style>'"
          type="textarea" autosize readonly/> -->
        </code>
      </pre>
      <div v-else style="padding:50px 0">
        <empty msg="正在刷新"/>
      </div>
    </div>
</template>

<script>
import Clipboard from 'clipboard'
export default {
  name: 'PreviewCodeView',
  props: {
    // 行数据
    row: {
      type: Array,
      // eslint-disable-next-line vue/require-valid-default-prop
      default: []
    },
    // 表单属性
    formConfig: {
      type: Object,
      default: undefined
    },
    // 行内列样式
    colStyle: {
      type: Object,
      default: undefined
    },
    // 表单验证
    formRules: {},
    codeShow: false
  },
  watch: {
    'row': {
      handler: function (e) {
        this.rows = e
        this.groupField()
        this.createCode()
      }
    },
    'formConfig': {
      handler: function (e) {
        this.form = e
      }
    },
    'colStyle': {
      handler: function (e) {
        this.colStyleConfig = e
      }
    },
    'codeShow': {
      handler: function (e) {
        // this.flushCode()
        this.codeShowFlag = e
      }
    }
  },
  components: {},
  data () {
    return {
      rows: this.row,
      form: this.formConfig || {
        lablePos: 'left',
        // 标签宽度
        labelWidth: 80,
        // 全局组件大小
        size: 'default'
      },
      colStyleConfig: this.colStyle || {},
      formField: {},
      // 预览代码
      previewCode: '',
      previewJSCode: '',
      // 复制组件
      clipboard: new Clipboard('.codeBtn'),
      codeShowFlag: this.codeShow
    }
  },
  methods: {
    groupField () {
      let rows = this.rows
      this.formField = this.lseutil.getGroupField(rows)
    },
    getContentCode (item) {
      let code = ``
      switch (item.configKey) {
        case 'input':
          code = `<div>
                <FormItem prop="${item.config.field}" label="${item.config.label}">
                    <Input v-model="formField.${item.config.field}" style="width:100%"
                    type="${item.config.type}"
                    size="${item.config.attr.size}" placeholder="${item.config.attr.placeholder}"
                    :clearable="${item.config.attr.clearable}" :readonly="${item.config.attr.readonly}"
                    :maxlength="${item.config.attr.maxlength}" :rows="${item.config.attr.rows}"
                    :autosize="${item.config.attr.autosize}" show-word-limit/>
                </FormItem>
          </div>`
          break
        case 'number':
          code = `<div>
                    <FormItem prop="${item.config.field}" label="${item.config.label}">
                        <InputNumber v-model="formField.${item.config.field}" style="width:100%"
                        :max="${item.config.attr.max}" :min="${item.config.attr.min}" :controls-outside="${item.config.attr.controlsOutside}"
                        :step="${item.config.attr.step}" size="${item.config.attr.size}"
                        placeholder="${item.config.attr.placeholder}"
                        :readonly="${item.config.attr.readonly}" :precision="${item.config.attr.precision}" :editable="${item.config.attr.editable}"
                        />
                    </FormItem>
                </div>`
          break
        case 'select':
          let selectOption = ''
          item.config.option.forEach(x => {
            selectOption += `<Option value="${x.value}">${x.label}</Option>`
          })
          code = `<div>
                    <FormItem prop="${item.config.field}" label="${item.config.label}">
                    <Select v-model="formField.${item.config.field}"
                    size="${item.config.attr.size}"  :disabled="${item.config.attr.disabled}"
                    :multiple="${item.config.attr.multiple}" :clearable="${item.config.attr.clearable}"
                    placeholder="${item.config.attr.placeholder}" :filterable="${item.config.attr.filterable}"
                    :allow-create="${item.config.attr.allowCreate}">
                        ${selectOption}
                    </Select>
                    </FormItem>
                </div>`
          break
        case 'time':
          code = `<div>
                    <FormItem prop="${item.config.field}" label="${item.config.label}">
                    <TimePicker style="width:100%" v-model="formField.${item.config.field}"
                    type="${item.config.type}" format="${item.config.attr.format}"
                    placeholder="${item.config.attr.placeholder}" size="${item.config.attr.size}"
                    :clearable="${item.config.attr.clearable}" :readonly="${item.config.attr.readonly}"
                    :editable="${item.config.attr.editable}"/>
                    </FormItem>
                </div>`
          break
        case 'date':
          code = `<div>
                    <FormItem prop="${item.config.field}" label="${item.config.label}">
                    <DatePicker style="width:100%" v-model="formField.${item.config.field}"
                    type="${item.config.type}" format="${item.config.attr.format}"
                    placeholder="${item.config.attr.placeholder}" size="${item.config.attr.size}"
                    :clearable="${item.config.attr.clearable}" :readonly="${item.config.attr.readonly}"
                    :editable="${item.config.attr.editable}"/>
                    </FormItem>
                </div>`
          break
        case 'switch':
          code = `<div>
                    <FormItem prop="${item.config.field}" label="${item.config.label}">
                    <SwitchIview v-model="formField.${item.config.field}"
                    size="${item.config.attr.size}" :disabled="${item.config.attr.disabled}"
                    true-value="${item.config.attr.trueVal}" false-value="${item.config.attr.falseVal}"
                    true-color="${item.config.attr.trueColor}" false-color="${item.config.attr.falseColor}"/>
                    </FormItem>
                </div>`
          break
        case 'radio':
          let radioOption = ''
          item.config.option.forEach(x => {
            radioOption += `<Radio :border="${item.config.attr.border}" label="${x.value}">${x.label}</Radio>`
          })
          code = `<div>
                    <FormItem prop="${item.config.field}" label="${item.config.label}">
                        <RadioGroup v-model="formField.${item.config.field}" button-style="solid"
                        :vertical="${item.config.attr.vertical}" size="${item.config.attr.size}"
                        type="${item.config.attr.type}"
                       >
                            ${radioOption}
                        </RadioGroup>
                    </FormItem>
                </div>`
          break
        case 'checkbox':
          let checkboxOption = ''
          item.config.option.forEach(x => {
            checkboxOption += `<Checkbox :border="${item.config.attr.border}" label="${x.value}">${x.label}</Checkbox>`
          })
          code = `<div>
                    <FormItem prop="${item.config.field}" label="${item.config.label}">
                        <CheckboxGroup  v-model="formField.${item.config.field}"
                            size="${item.config.attr.size}"
                       >
                        ${checkboxOption}
                        </CheckboxGroup>
                    </FormItem>
                </div>`
          break
        case 'button':
          code = `<div>
                    <Button size="${item.config.attr.size}" type="${item.config.attr.type}"
                    :ghost="${item.config.attr.ghost}" :long="${item.config.attr.long}"
                    :disabled="${item.config.attr.disabled}">${item.config.text}</Button>
                </div>`
          break
        case 'divider':
          code = `<div>
                    <Divider type="${item.config.attr.type}"
                    :orientation="${item.config.attr.orientation}"
                    :dashed="${item.config.attr.dashed}"
                    :plain="${item.config.attr.plain}">${item.config.text}</Divider>
                </div>`
          break
        case 'text':
          let textStyle = item.config.attr.style || `padding: ${item.config.attr.padding}px;
          font-weight:${item.config.attr.bold ? 'bold' : 'normal'};font-size:${item.config.attr.fontSize}px;text-align:${item.config.attr.align}`
          code = `<div>
                    <div style="${textStyle}">${item.config.content}</div>
                </div>`
          break
        case 'alert':
          let closeText = item.config.attr.closeText
            ? `<template  slot="close">${item.config.attr.closeText}</template>` : ''
          code = `<div>
                    <Alert type="${item.config.attr.type}" :closable="${item.config.attr.closable}"
                    :show-icon="${item.config.attr.showIcon}">
                    ${item.config.title}
                    <template  slot="desc">${item.config.content}</template>
                    ${closeText}
                    </Alert>
                </div>`
          break

        default:
          break
      }
      return code
    },
    createCode () {
      let content = ''
      let methods = []
      let rows = this.rows
      rows.forEach((cols, ri) => {
        let rowDiv = ''
        cols.forEach((eles, coli) => {
          let colDiv = ''
          eles.forEach((item, itemi) => {
            let code = this.getContentCode(item)
            let div = `<div style="display: ${item.config.hide ? 'none' : 'block'}">${code}</div>`
            colDiv += div
            if (item.config.click) {
              methods.push(
                `fun${coli}${itemi} () {
                  ${item.config.click}
                }`
              )
            }
          })
          let col = `
            <div style="${this.colStyleConfig[ri + '-' + coli] || 'width:100%;margin:0 5px'}">${colDiv}</div>
          `
          rowDiv += col
        })
        let row = `<div style="display:flex;margin-top:10px">${rowDiv}</div>`
        content += row
      })
      // 生成字段
      let field = ''
      for (const key in this.formField) {
        let val = ''
        if (typeof (this.formField[key]) === 'object' && this.formField[key].length === undefined) {
          val = this.lseutil.objCopy(this.formField[key])
        } else if (typeof (this.formField[key]) === 'object' && this.formField[key].length >= 0) {
          val = this.lseutil.arrayCopy(this.formField[key])
        } else {
          val = this.formField[key]
        }
        field += `${key}: ${JSON.stringify(val)},`
      }
      field = field.substring(0, field.length - 1)
      let code = `
      <template>
      <div ref="formPreview" id="formPreview">
        <Form ref="form" :model="formField" :rules="formRules" :label-width="${this.form.labelWidth}" style="text-align:left"
        label-position="${this.form.lablePos}" size="${this.form.size}">
        ${content}
        </Form>
      </div>
      </template>`
      this.previewCode = code
      this.previewJSCode = `
        export default {
            name: 'Preview',
            data () {
              return {
                formField: {${field}},
                formRules: ${JSON.stringify(this.formRules)}
              }
            },
            props: {},
            watch: {},
            components: {},
            methods: {
              ${methods.join(',\n')}
            },
            mounted () {},
            created () {}
        }`
    },
    copy () {
    },
    flushCode () {
      this.createCode()
      this.codeShowFlag = false
      setTimeout(() => {
        this.codeShowFlag = true
      }, 500)
    }
  },
  mounted () {
    this.groupField()
    this.createCode()
    let that = this
    let cl = this.clipboard
    cl.on('success', function (e) {
      that.lseutil.msg({
        msg: '复制成功',
        type: 1
      })
      e.clearSelection()
    })
    cl.on('error', function (e) {
      that.lseutil.msg({
        msg: '复制失败',
        type: 2
      })
      e.clearSelection()
    })
  }
}
</script>

<style scoped>

</style>
